<template xmlns="http://www.w3.org/1999/html">
  <div class="page-wrapper">
    <!-- Page body -->
    <div class="page-body">
      <div class="container-xl">
        <div class="row row-deck row-cards">

          <div class="col-12">
            <div class="card">
              <div class="card-header">
                <div class="row g-2 align-items-center">
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-primary w-100" @click="openAddMachine"
                       data-bs-target="#modal-add-machine">
                      新增机器
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-info w-100" @click="openEditMachine">
                      修改机器
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-secondary w-100" @click="confirmDelete">
                      删除机器
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-success w-100" @click="callOpenMachinePluginRef">
                      管理插件
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-warning w-100" @click="changeMachineStatus('启用', 1)">
                      启用
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-secondary w-100" @click="changeMachineStatus('禁用', 0)">
                      禁用
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-warning w-100" @click="restartMachine(1)">
                      启动程序
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-secondary w-100" @click="restartMachine(-1)">
                      停用程序
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-success w-100" @click="restartMachine(0)">
                      重启机器
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-info w-100" @click="openUrl">
                      访问admin
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-primary w-100" @click="fetchData">
                      刷新列表
                    </a>
                  </div>
                  <div class="col-6 col-sm-4 col-md-2 col-xl py-0">
                    <a href="#" class="btn btn-info w-100" @click="toggleSearchPanel">
                      {{ showSearchPanel ? '收起搜索' : '高级搜索' }}
                    </a>
                  </div>


                </div>
              </div>
              
              <!-- 高级搜索面板 -->
              <div class="card-body border-bottom" v-show="showSearchPanel">
                <div class="row g-3">
                  <div class="col-md-2">
                    <label class="form-label">机器标签</label>
                    <select class="form-select" v-model="searchParams.label">
                      <option value="">全部标签</option>
                      <option v-for="type in typeList" :key="type.value" :value="type.value">
                        {{ type.label }}
                      </option>
                    </select>
                  </div>
                  <div class="col-md-2">
                    <label class="form-label">机器状态</label>
                    <select class="form-select" v-model="searchParams.status">
                      <option value="">全部状态</option>
                      <option value="1">启用</option>
                      <option value="0">禁用</option>
                    </select>
                  </div>
                  <div class="col-md-2">
                    <label class="form-label">健康状态</label>
                    <select class="form-select" v-model="searchParams.health">
                      <option value="">全部</option>
                      <option value="1">健康</option>
                      <option value="0">未知</option>
                    </select>
                  </div>
                  <div class="col-md-2">
                    <label class="form-label">黑屏状态</label>
                    <select class="form-select" v-model="searchParams.isBlackScreen">
                      <option value="">全部</option>
                      <option value="0">正常</option>
                      <option value="1">黑屏</option>
                      <option value="-1">未知</option>
                    </select>
                  </div>
                  <div class="col-md-2">
                    <label class="form-label">IP地址</label>
                    <input type="text" 
                           class="form-control" 
                           v-model="searchParams.ip"
                           placeholder="搜索IP地址">
                  </div>
                  <div class="col-md-2">
                    <label class="form-label">版本号</label>
                    <input type="text" 
                           class="form-control" 
                           v-model="searchParams.version"
                           placeholder="搜索版本号">
                  </div>

                </div>
                <div class="row mt-3">
                  <div class="col-12">
                    <button class="btn btn-primary me-2" @click="handleSearch">
                      搜索
                    </button>
                    <button class="btn btn-secondary" @click="resetSearch">
                      重置
                    </button>
                  </div>
                </div>
              </div>
              <div class="card-body border-bottom py-3">
                <div class="d-flex">
                  <div class="text-secondary">
                    共 {{ paginationInfo.total || 0 }} 台机器
                  </div>
                  <div class="ms-auto">
                    <!-- 分页信息 -->
                    <span class="text-secondary me-3">
                      第 {{ paginationInfo.current || 1 }} 页 / 共 {{ paginationInfo.pages || 1 }} 页
                    </span>
                    <div class="btn-group">
                      <button class="btn btn-sm btn-outline-primary" 
                              @click="goToPage(1)" 
                              :disabled="paginationInfo.current <= 1">
                        首页
                      </button>
                      <button class="btn btn-sm btn-outline-primary" 
                              @click="goToPage(paginationInfo.current - 1)" 
                              :disabled="paginationInfo.current <= 1">
                        上一页
                      </button>
                      <button class="btn btn-sm btn-outline-primary" 
                              @click="goToPage(paginationInfo.current + 1)" 
                              :disabled="paginationInfo.current >= paginationInfo.pages">
                        下一页
                      </button>
                      <button class="btn btn-sm btn-outline-primary" 
                              @click="goToPage(paginationInfo.pages)" 
                              :disabled="paginationInfo.current >= paginationInfo.pages">
                        末页
                      </button>
                    </div>
                  </div>
                </div>
              </div>
              <div class="table-responsive">
                <table class="table card-table table-vcenter text-nowrap datatable">
                  <thead>
                  <tr>
                    <th><input class="form-check-input m-0 align-middle" type="checkbox" v-model="isAllChecked"
                               @change="handleToggleAllCheckboxes"></th>
                    <th class="w-1">ID</th>
                    <th>IP</th>
                    <th>标签</th>
                    <th>状态信息</th>
                    <th>运行状态</th>
                    <th class="sortable-header" @click="handleSort('lastUpdateTime')">
                      机器时间信息
                      <span class="sort-indicators">
                        <i class="sort-icon" :class="{
                          'sort-up': sortState.lastUpdateTime === 'asc',
                          'sort-down': sortState.lastUpdateTime === 'desc',
                          'sort-none': sortState.lastUpdateTime === null
                        }"></i>
                      </span>
                    </th>
                    <th>备注</th>
                  </tr>
                  </thead>
                  <tbody>

                  <!-- 使用 v-for 指令循环渲染表格行 -->
                  <tr v-for="(item, index) in tableData" 
                      :key="index"
                      @click="toggleRowCheckbox(tableData, item)"
                      :class="{'selected-row': item.checked}">
                    <td><input class="form-check-input m-0 align-middle" type="checkbox" v-model="item.checked"></td>
                    <td><span class="text-secondary">{{ item.id }}</span></td>
                    <td>{{ item.ip }}</td>
                    <td>
                      <div class="d-flex align-items-center">
                        {{ item.label }}
                        <a v-if="item.label === 'py-远程'" 
                           :href="baseUrl + '/machine-manage/' + item.id"
                           class="badge bg-blue-lt ms-2">
                          管理
                        </a>
                      </div>
                    </td>
                    <td>
                      <div class="status-info-container">
                        <!-- 机器状态 -->
                        <div class="status-info-item">
                          <span class="status-info-label">状态:</span>
                          <span :class="{
                            'badge': true,
                            'bg-green-lt': item.status === 1,
                            'bg-red-lt': item.status === 0
                          }">
                            {{ item.statusStr }}
                          </span>
                        </div>
                        
                        <!-- 版本信息 -->
                        <div class="status-info-item" v-if="item.version">
                          <span class="status-info-label">版本:</span>
                          <span class="version-badge-compact">{{ item.version }}</span>
                        </div>
                        
                        <!-- 服务按钮 -->
                        <div class="status-info-item">
                          <span class="status-info-label">服务:</span>
                          <div class="service-buttons-compact">
                            <a :href="`http://${item.ip}:8510/info`" 
                               target="_blank" 
                               class="btn btn-xs btn-outline-primary"
                               @click.stop
                               title="查看机器服务信息">
                              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <circle cx="12" cy="12" r="10"></circle>
                                <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path>
                                <path d="M12 17h.01"></path>
                              </svg>
                            </a>
                            <a :href="`http://${item.ip}:8520/manager/info`" 
                               target="_blank" 
                               class="btn btn-xs btn-outline-success"
                               @click.stop
                               title="查看管理器信息">
                              <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                                <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>
                              </svg>
                            </a>
                          </div>
                        </div>
                      </div>
                    </td>
                    <td>
                      <div class="status-container">
                        <!-- 健康状态 -->
                        <div class="status-item sortable-health-item" @click.stop="handleSort('healthUpdateTime')">
                          <span class="status-label">
                            健康状态:
                            <i class="sort-icon-small" :class="{
                              'sort-up': sortState.healthUpdateTime === 'asc',
                              'sort-down': sortState.healthUpdateTime === 'desc',
                              'sort-none': sortState.healthUpdateTime === null
                            }"></i>
                          </span>
                          <div class="health-info">
                            <span :class="{
                              'badge': true,
                              'bg-green': item.health === true,
                              'bg-red': item.health === false,
                              'bg-gray': item.health === null || item.health === undefined
                            }">
                              {{ item.health === true ? '健康' : item.health === false ? '掉线' : '未知' }}
                            </span>
                            <div v-if="item.healthUpdateTime" class="health-time">
                              <span :class="{
                                'time-badge': true,
                                'bg-green': item.health === true,
                                'bg-red': item.health === false,
                                'bg-gray': item.health === null || item.health === undefined
                              }">
                                {{ item.healthUpdateTime }}
                              </span>
                            </div>
                          </div>
                        </div>
                        
                        <!-- 黑屏状态 -->
                        <div class="status-item">
                          <span class="status-label">屏幕状态:</span>
                          <span :class="{
                            'badge': true,
                            'bg-orange': item.isBlackScreen === 1,
                            'bg-green': item.isBlackScreen === 0,
                            'bg-gray': item.isBlackScreen === -1 || item.isBlackScreen === null
                          }">
                            {{ item.isBlackScreen === 1 ? '黑屏' : item.isBlackScreen === 0 ? '正常' : '未知' }}
                          </span>
                        </div>
                      </div>
                    </td>
                    <td>
                      <div class="time-info-container">
                        <!-- 最后修改时间 -->
                        <div class="time-info-item sortable-time-item" @click.stop="handleSort('lastUpdateTime')">
                          <span class="time-label">
                            最后修改:
                            <i class="sort-icon-small" :class="{
                              'sort-up': sortState.lastUpdateTime === 'asc',
                              'sort-down': sortState.lastUpdateTime === 'desc',
                              'sort-none': sortState.lastUpdateTime === null
                            }"></i>
                          </span>
                          <span class="time-value">{{ item.lastUpdateTime }}</span>
                        </div>
                        
                        <!-- VM启动时间 -->
                        <div class="time-info-item sortable-time-item" v-if="item.vmStartTime" @click.stop="handleSort('vmStartTime')">
                          <span class="time-label">
                            VM启动:
                            <i class="sort-icon-small" :class="{
                              'sort-up': sortState.vmStartTime === 'asc',
                              'sort-down': sortState.vmStartTime === 'desc',
                              'sort-none': sortState.vmStartTime === null
                            }"></i>
                          </span>
                          <span class="time-value">{{ item.vmStartTime }}</span>
                        </div>
                        
                        <!-- 机器启动时间 -->
                        <div class="time-info-item sortable-time-item" v-if="item.bootStartTime" @click.stop="handleSort('bootStartTime')">
                          <span class="time-label">
                            系统启动:
                            <i class="sort-icon-small" :class="{
                              'sort-up': sortState.bootStartTime === 'asc',
                              'sort-down': sortState.bootStartTime === 'desc',
                              'sort-none': sortState.bootStartTime === null
                            }"></i>
                          </span>
                          <span class="time-value">{{ item.bootStartTime }}</span>
                        </div>
                        
                        <!-- 最后远程时间 -->
                        <div class="time-info-item sortable-time-item" v-if="item.lastRemoteTime" @click.stop="handleSort('lastRemoteTime')">
                          <span class="time-label">
                            最后远程:
                            <i class="sort-icon-small" :class="{
                              'sort-up': sortState.lastRemoteTime === 'asc',
                              'sort-down': sortState.lastRemoteTime === 'desc',
                              'sort-none': sortState.lastRemoteTime === null
                            }"></i>
                          </span>
                          <span class="time-value">{{ item.lastRemoteTime }}</span>
                        </div>
                      </div>
                    </td>
                    <td :title="item.remark">
                      {{ truncateText(item.remark, 30) }}
                    </td>
                  </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>


        </div>

      </div>

    </div>

  </div>

  <!-- 删除原有的新增机器模态框 -->
  <ComponentModal
      :modalId="'modal-success-machine'"
      :title="'信息'"
      :message="'操作成功'"
      :cancelText="'取消'"
      :confirmText="'确定'"
      ref="componentModalOutRef"
  />

  <MachinePluginRef ref="machinePluginRef" @updateSuccessEvent="fetchData"/>
  <EditMachineModal ref="editMachineModalRef" :typeList="typeList" @update-success="fetchData"/>
  <AddMachineModal ref="addMachineModalRef" :typeList="typeList" @add-success="fetchData"/>
  <Loading ref="loadingRef"/>

</template>


<script setup>
import {ref, reactive, onMounted, computed, inject, nextTick, watch} from 'vue';
import ComponentModal from '@/components/ComponentModal.vue';
import Loading from '@/components/Loading.vue';
import MachinePluginRef from "./MachinePluginRef.vue";
import {Modal} from 'bootstrap';
import { useTableMixin } from '@/mixins/tableMixin';
import EditMachineModal from "./EditMachineModal.vue";
import AddMachineModal from "./AddMachineModal.vue";
import { useRouter } from 'vue-router';

const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;
const baseUrl = import.meta.env.BASE_URL;
// 表格数据和分页信息
const tableData = ref([]);
const isAllChecked = ref(false);
const typeList = ref([]); // 添加标签列表

// 分页参数
const pageParams = ref({
  offset: 0,
  limit: 20,
  sort: 'last_update_time',
  order: 'desc'
});

// 排序状态
const sortState = ref({
  bootStartTime: null,
  healthUpdateTime: null,
  vmStartTime: null,
  lastRemoteTime: null,
  lastUpdateTime: 'desc'
});

// 分页信息
const paginationInfo = ref({
  total: 0,
  current: 1,
  pages: 1,
  size: 20
});

// 搜索面板状态
const showSearchPanel = ref(false);

// 搜索参数
const searchParams = ref({
  label: '',
  status: '',
  ip: '',
  isBlackScreen: '',
  health: '',
  version: ''
});

const componentModalOutRef = ref(null);
const loadingRef = ref(null);
const machinePluginRef = ref(null);
const editMachineModalRef = ref(null);
const addMachineModalRef = ref(null);

const { 
  toggleAllCheckboxes,
  toggleRowCheckbox,
  getSelectedIds,
  hasSelectedItems,
  resetSelection 
} = useTableMixin();

let machineHealth = '<span class="badge bg-yellow text-yellow-fg">请求中 ... </span>';

let addMachineModal;
nextTick(() => {
  // 添加机器模态框
  addMachineModal = new Modal(document.getElementById('modal-add-machine'));
});

const router = useRouter();

const openUrl = () => {
  if (typeof window !== 'undefined' && typeof window.open === 'function') {
    window.open('http://10.100.1.1:31110/applications/resident-manager?q=resident-manager', '_blank');
  } else {
    console.error('window 对象或 window.open 方法不可用');
  }
};

const restartMachine = async (operateNum) => {
  let ids = [];
  let hasDisabled = false;
  
  tableData.value.forEach(item => {
    if (item.checked) {
      ids.push(item.id);
      if (item.status === 0) {
        hasDisabled = true;
      }
    }
  });

  if (ids.length === 0) {
    componentModalOutRef.value.openWarnModal('请选择需要操作的元素');
    return;
  }

  if (hasDisabled) {
    componentModalOutRef.value.openWarnModal('禁用状态的机器无法执行此操作');
    return;
  }

  const idStr = ids.join(',');
  let text = '重启';
  if (operateNum == 0) {
    text = '重启';
  } else if (operateNum == 1) {
    text = '启动';
  } else if (operateNum == -1) {
    text = '停用';
  }

  componentModalOutRef.value.openWarnModal(`确定${text} ${idStr} 的机器吗?`, async () => {
    loadingRef.value.openLoading();
    const url = `${apiBaseUrl}/resident/machine/restart?machineIds=${idStr}&operateNum=${operateNum}`;
    const response = await fetch(url, {
      method: 'POST'
    }).then(response => response.json())
        .then(data => {
          setTimeout(() => {
              fetchData();
            }, 500);
          if (data.success) {
            componentModalOutRef.value.openInfoModal('操作完成！');
          } else {
            componentModalOutRef.value.openWarnModal("操作失败：" + data.message);
          }
          loadingRef.value.closeLoading();
        })
        .catch(error => {
          componentModalOutRef.value.openWarnModal('操作失败，请稍后重试！');
          loadingRef.value.closeLoading();
        });
  });
}

// 启用,禁用
const changeMachineStatus = (text, status) => {
  let ids = [];
  tableData.value.forEach(item => {
    if (item.checked) {
      ids.push(item.id);
    }
  });
  if (ids.length > 0) {
    const idStr = ids.join(',');
    componentModalOutRef.value.openWarnModal(`确定${text} ${idStr} 的机器吗?`, async () => {
      try {
        let url = `${apiBaseUrl}/resident/machine/status?status=${status}&pluginIds=${idStr}`;
        const response = await fetch(url, {
          method: 'POST'
        });
        const data = await response.json();
        if (data.success) {
          componentModalOutRef.value.openInfoModal(`${text}成功！`);
        }
      } catch (error) {
        componentModalOutRef.value.openWarnModal(`${text}失败！`);
      }
      fetchData();
    });
  } else {
    componentModalOutRef.value.openWarnModal('请选择需要操作的元素');
  }
}


const callOpenMachinePluginRef = () => {
  let checkedIds = [];
  tableData.value.forEach(item => {
    if (item.checked) {
      checkedIds.push(item.id);
    }
  });
  if (checkedIds.length > 0) {
    let machineIds = checkedIds.join(',');
    machinePluginRef.value.openMachinePluginRef(machineIds);
  } else {
    componentModalOutRef.value.openWarnModal('请选择需要操作的元素');
  }

}


// 处理确认事件
const confirmDelete = () => {
  const delIds = getSelectedIds(tableData.value);
  if (delIds.length > 0) {
    componentModalOutRef.value.openWarnModal('确定删除' + delIds.join(', ') + '的机器吗?', async () => {
      try {
        let deleteUrl = apiBaseUrl + '/resident/machine/delete?machineIds=' + delIds.join(',');
        const response = await fetch(deleteUrl, {
          method: 'DELETE'
        });
        const data = await response.json();
        if (data.success) {
          componentModalOutRef.value.openInfoModal('删除成功！');
        }
      } catch (error) {
        componentModalOutRef.value.openWarnModal('删除失败！');
      }
      fetchData();
    });
  } else {
    componentModalOutRef.value.openWarnModal('请选择元素');
  }
};


// 处理全选/全不选逻辑
const handleToggleAllCheckboxes = () => {
  toggleAllCheckboxes(tableData.value, isAllChecked.value);
};

// 监听表格数据变化，更新全选状态
watch(tableData, () => {
  isAllChecked.value = tableData.value.length > 0 && tableData.value.every(item => item.checked);
}, { deep: true });

// 分页跳转
const goToPage = (page) => {
  if (page < 1 || page > paginationInfo.value.pages) return;
  
  pageParams.value.offset = (page - 1) * pageParams.value.limit;
  paginationInfo.value.current = page;
  fetchData();
};

// 切换搜索面板
const toggleSearchPanel = () => {
  showSearchPanel.value = !showSearchPanel.value;
};

// 处理搜索
const handleSearch = () => {
  // 重置分页到第一页
  pageParams.value.offset = 0;
  paginationInfo.value.current = 1;
  fetchData();
};

// 重置搜索条件
const resetSearch = () => {
  searchParams.value = {
    label: '',
    status: '',
    ip: '',
    isBlackScreen: '',
    health: '',
    version: ''
  };
  handleSearch();
};

// 排序功能
const handleSort = (field) => {
  // 重置其他字段的排序状态
  Object.keys(sortState.value).forEach(key => {
    if (key !== field) {
      sortState.value[key] = null;
    }
  });
  
  // 切换当前字段的排序状态
  if (sortState.value[field] === null) {
    sortState.value[field] = 'desc';
  } else if (sortState.value[field] === 'desc') {
    sortState.value[field] = 'asc';
  } else {
    sortState.value[field] = 'desc';
  }
  
  // 更新分页参数
  pageParams.value.sort = field;
  pageParams.value.order = sortState.value[field];
  
  // 重置到第一页
  pageParams.value.offset = 0;
  paginationInfo.value.current = 1;
  
  // 执行查询
  fetchData();
};

// 查询数据的函数
const fetchData = async () => {
  try {
    // 构建请求参数
    const requestData = {
      offset: pageParams.value.offset,
      limit: pageParams.value.limit,
      sort: pageParams.value.sort,
      order: pageParams.value.order,
      search: {}
    };

    // 添加搜索条件
    if (searchParams.value.label) {
      requestData.search.label = searchParams.value.label;
    }
    if (searchParams.value.status !== '') {
      requestData.search.status = parseInt(searchParams.value.status);
    }
    if (searchParams.value.ip) {
      requestData.search.ip = searchParams.value.ip;
    }
    if (searchParams.value.isBlackScreen !== '') {
      requestData.search.isBlackScreen = parseInt(searchParams.value.isBlackScreen);
    }
    if (searchParams.value.health !== '') {
      requestData.search.health = parseInt(searchParams.value.health);
    }
    if (searchParams.value.version) {
      requestData.search.version = searchParams.value.version;
    }

    const response = await fetch(apiBaseUrl + '/resident/machine/search', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(requestData)
    });
    
    const data = await response.json();
    if (data.success) {
      const records = data.result.records || [];
      tableData.value = records.map(item => {
        let statusStr;
        if (item.status === 1) {
          statusStr = '启用';
        } else {
          statusStr = '禁用';
        }
        return {
          ...item,
          checked: false,
          statusStr,
          // 从新接口直接获取健康状态信息
          health: item.health, // 直接使用接口返回的health字段
          label: item.label || item.type // 兼容旧数据
        };
      });
      
      // 更新分页信息
      paginationInfo.value = {
        total: data.result.total || 0,
        current: data.result.current || 1,
        pages: data.result.pages || 1,
        size: data.result.size || 20
      };
    }
  } catch (error) {
    console.error('Error fetching data:', error);
  }
};


const openAddMachine = () => {
  addMachineModalRef.value.openModal();
};

const submitAddMachine = async (event) => {
  event.preventDefault();
  event.stopPropagation();
  
  // 获取表单元素
  const form = document.getElementById('addMachineForm');
  
  // 添加验证样式类
  form.classList.add('was-validated');
  
  // 检查表单验证
  if (!form.checkValidity()) {
    return;
  }

  const formData = new FormData(form);
  const data = {};
  formData.forEach((value, key) => {
    data[key] = value;
  });

  try {
    const queryParams = new URLSearchParams(data).toString();
    const url = `${apiBaseUrl}/resident/machine/add?${queryParams}`;
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    });
    
    const apiResult = await response.json();
    if (apiResult.success) {
      componentModalOutRef.value.openInfoModal('添加成功！');
      addMachineModal.hide();
      // 重置表单验证状态
      form.classList.remove('was-validated');
      form.reset();
      fetchData();
    } else {
      componentModalOutRef.value.openWarnModal('请求错误:' + apiResult.errorMsg);
    }
  } catch (error) {
    componentModalOutRef.value.openWarnModal('保存失败，请稍后重试！');
    console.error('Save error:', error);
  }
};

// 获取标签列表
const fetchTypeList = async () => {
  try {
    const response = await fetch(apiBaseUrl + '/resident/plugin-label/list-select');
    const data = await response.json();
    if (data.success) {
      typeList.value = data.result.map(item => ({
        value: item.name,
        label: item.name
      }));
    }
  } catch (error) {
    console.error('Error fetching type list:', error);
    componentModalOutRef.value.openWarnModal('加载标签列表失败，请稍后重试！');
  }
};

// 页面加载时查询数据
onMounted(() => {
  fetchData();
  fetchTypeList(); // 获取标签列表
});

// 添加文本截断函数
const truncateText = (text, length) => {
  if (!text) return '';
  return text.length > length ? text.substring(0, length) + '...' : text;
};

const truncatePluginName = (name) => {
  if (!name) return '';
  return name.length > 20 ? name.substring(0, 20) + '...' : name;
};

const openEditMachine = () => {
  const selectedItems = tableData.value.filter(item => item.checked);
  if (selectedItems.length !== 1) {
    componentModalOutRef.value.openWarnModal('请选择一条记录进行修改');
    return;
  }
  editMachineModalRef.value.openModal(selectedItems[0]);
};

const openVmMachineModal = (machine) => {
  router.push(`/machine-manage/${machine.id}`);
};
</script>

<style scoped>
/* ... 其他样式保持不变 ... */

.plugins-cell {
  width: 300px !important;
  min-width: 300px !important;
  max-width: 300px !important;
}

.plugins-container {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  width: 100%;
}

.plugin-badge {
  margin: 2px;
  padding: 5px 8px;
  font-size: 0.85em;
  background-color: rgba(32, 107, 196, 0.1);
  border: 1px solid rgba(32, 107, 196, 0.2);
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-width: 80px;
}

.plugin-name {
  font-weight: 500;
  margin-bottom: 2px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: help;
}

.plugin-version {
  font-size: 0.8em;
  color: #666;
}

/* 状态样式 */
.bg-green-lt {
  background-color: rgba(40, 167, 69, 0.15) !important;
  color: #2fb344 !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

.bg-red-lt {
  background-color: rgba(220, 53, 69, 0.15) !important;
  color: #d63939 !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

/* 表格样式优化 */
.table td {
  padding: 0.75rem;
  vertical-align: middle;
}

.table th {
  font-weight: 600;
  background-color: #f8f9fa;
  border-bottom: 2px solid #dee2e6;
}

/* 健康状态样式优化 */
:deep(.badge) {
  padding: 0.4em 0.8em;
  font-size: 0.875em;
  font-weight: 500;
}

:deep(.bg-green) {
  background-color: #2fb344 !important;
}

:deep(.bg-red) {
  background-color: #d63939 !important;
}

:deep(.bg-yellow) {
  background-color: #f59f00 !important;
}

/* 必填项样式 */
.required:after {
  content: " *";
  color: red;
}

/* 表单验证样式 */
.form-control:invalid,
.form-select:invalid {
  border-color: #dc3545;
}

.form-control:invalid:focus,
.form-select:invalid:focus {
  border-color: #dc3545;
  box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
}

/* 添加 Bootstrap 原生验证样式 */
.was-validated .form-control:invalid,
.was-validated .form-select:invalid {
  border-color: #dc3545;
  padding-right: calc(1.5em + 0.75rem);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right calc(0.375em + 0.1875rem) center;
  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

.was-validated .form-control:valid,
.was-validated .form-select:valid {
  border-color: #198754;
  padding-right: calc(1.5em + 0.75rem);
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right calc(0.375em + 0.1875rem) center;
  background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

.invalid-feedback {
  display: none;
  width: 100%;
  margin-top: 0.25rem;
  font-size: 0.875em;
  color: #dc3545;
}

.was-validated .form-control:invalid ~ .invalid-feedback,
.was-validated .form-select:invalid ~ .invalid-feedback {
  display: block;
}

/* 添加备注列的样式 */
td[title] {
  cursor: help;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 添加选中行的样式 */
.selected-row {
  background-color: rgba(32, 107, 196, 0.1) !important;
}

tr {
  cursor: pointer;
  transition: background-color 0.2s ease;
}

tr:hover {
  background-color: rgba(32, 107, 196, 0.05);
}

/* 防止点击复选框时触发行点击事件 */
tr input[type="checkbox"] {
  cursor: pointer;
  pointer-events: auto;
}

/* 添加蓝色标签样式 */
.bg-blue-lt {
  background-color: rgba(32, 107, 196, 0.15) !important;
  color: #206bc4 !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

/* 状态容器样式 */
.status-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
  background-color: #f8f9fa;
  border-radius: 6px;
  min-width: 280px;
}

.status-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 0;
}

.status-label {
  font-size: 0.875em;
  color: #6c757d;
  font-weight: 500;
  margin-right: 8px;
  min-width: 70px;
}

.status-time {
  font-size: 0.875em;
  color: #495057;
  font-family: monospace;
  background-color: rgba(108, 117, 125, 0.1);
  padding: 2px 6px;
  border-radius: 3px;
}

/* 状态标签样式 */
.bg-orange {
  background-color: #fd7e14 !important;
  color: white !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

.bg-gray {
  background-color: #6c757d !important;
  color: white !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

.bg-green {
  background-color: #198754 !important;
  color: white !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

.bg-red {
  background-color: #dc3545 !important;
  color: white !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

.bg-yellow {
  background-color: #ffc107 !important;
  color: #212529 !important;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 0.875em;
}

/* 分页按钮样式 */
.btn-group .btn {
  font-size: 0.875rem;
  padding: 0.375rem 0.75rem;
}

.btn-outline-primary {
  color: #3b82f6;
  border-color: #3b82f6;
}

.btn-outline-primary:hover {
  background-color: #3b82f6;
  border-color: #3b82f6;
  color: white;
}

.btn-outline-primary:disabled {
  color: #9ca3af;
  border-color: #9ca3af;
  cursor: not-allowed;
}

/* 高级搜索面板样式 */
.form-label {
  font-weight: 500;
  margin-bottom: 0.5rem;
  color: #374151;
}

.form-select, .form-control {
  border: 1px solid #d1d5db;
  border-radius: 0.375rem;
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.form-select:focus, .form-control:focus {
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.btn-info {
  background-color: #06b6d4;
  border-color: #06b6d4;
  color: white;
}

.btn-info:hover {
  background-color: #0891b2;
  border-color: #0891b2;
}

/* 时间信息容器样式 */
.time-info-container {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
  background-color: #f8f9fa;
  border-radius: 6px;
  min-width: 200px;
}

.time-info-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 0;
}

.time-label {
  font-size: 0.875em;
  color: #6c757d;
  font-weight: 500;
  margin-right: 8px;
  min-width: 60px;
}

.time-value {
  font-size: 0.875em;
  color: #495057;
  font-family: monospace;
  background-color: rgba(108, 117, 125, 0.1);
  padding: 2px 6px;
  border-radius: 3px;
}

/* 状态信息容器样式 */
.status-info-container {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px;
  background-color: #f8f9fa;
  border-radius: 6px;
  min-width: 150px;
}

.status-info-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 0;
}

.status-info-label {
  font-size: 0.875em;
  color: #6c757d;
  font-weight: 500;
  margin-right: 6px;
  min-width: 35px;
}

.version-badge-compact {
  font-size: 0.75em;
  font-weight: 600;
  color: #ffffff;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  padding: 2px 6px;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  min-width: 30px;
  text-align: center;
}

/* 健康状态信息样式 */
.health-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-end;
}

.health-time {
  margin-top: 2px;
}

.time-badge {
  font-size: 0.75em;
  font-weight: 400;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: monospace;
  display: inline-block;
  opacity: 0.8;
}

/* 排序相关样式 */
.sortable-header {
  cursor: pointer;
  user-select: none;
  position: relative;
  transition: background-color 0.2s ease;
}

.sortable-header:hover {
  background-color: rgba(0, 0, 0, 0.05);
}

.sortable-time-item {
  cursor: pointer;
  transition: background-color 0.2s ease;
  border-radius: 3px;
  padding: 2px 4px;
}

.sortable-time-item:hover {
  background-color: rgba(32, 107, 196, 0.1);
}

.sortable-health-item {
  cursor: pointer;
  transition: background-color 0.2s ease;
  border-radius: 3px;
  padding: 2px 4px;
}

.sortable-health-item:hover {
  background-color: rgba(32, 107, 196, 0.1);
}

.sort-indicators {
  margin-left: 8px;
  display: inline-block;
}

.sort-icon {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 4px;
  vertical-align: middle;
}

.sort-icon.sort-up {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 6px solid #206bc4;
}

.sort-icon.sort-down {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 6px solid #206bc4;
}

.sort-icon.sort-none {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 3px solid #ccc;
  border-bottom: 3px solid #ccc;
  margin-top: -1px;
}

.sort-icon-small {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 4px;
  vertical-align: middle;
}

.sort-icon-small.sort-up {
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-bottom: 4px solid #206bc4;
}

.sort-icon-small.sort-down {
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-top: 4px solid #206bc4;
}

.sort-icon-small.sort-none {
  border-left: 3px solid transparent;
  border-right: 3px solid transparent;
  border-top: 2px solid #ccc;
  border-bottom: 2px solid #ccc;
  margin-top: -1px;
}

/* 服务按钮样式 */
.service-buttons {
  display: flex;
  gap: 6px;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

.service-buttons .btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  font-size: 0.75rem;
  line-height: 1.2;
  border-radius: 4px;
  text-decoration: none;
  transition: all 0.2s ease;
  white-space: nowrap;
}

.service-buttons .btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.service-buttons .btn svg {
  flex-shrink: 0;
}

.service-buttons .btn-outline-primary {
  color: #0d6efd;
  border-color: #0d6efd;
}

.service-buttons .btn-outline-primary:hover {
  background-color: #0d6efd;
  border-color: #0d6efd;
  color: white;
}

.service-buttons .btn-outline-success {
  color: #198754;
  border-color: #198754;
}

.service-buttons .btn-outline-success:hover {
  background-color: #198754;
  border-color: #198754;
  color: white;
}

/* 紧凑服务按钮样式 */
.service-buttons-compact {
  display: flex;
  gap: 4px;
  align-items: center;
}

.service-buttons-compact .btn {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px 4px;
  font-size: 0.7rem;
  line-height: 1;
  border-radius: 3px;
  text-decoration: none;
  transition: all 0.2s ease;
  min-width: 24px;
  height: 24px;
}

.service-buttons-compact .btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.service-buttons-compact .btn svg {
  flex-shrink: 0;
}

.btn-xs {
  padding: 2px 4px;
  font-size: 0.7rem;
  line-height: 1;
  border-radius: 3px;
}

.service-buttons-compact .btn-outline-primary {
  color: #0d6efd;
  border-color: #0d6efd;
}

.service-buttons-compact .btn-outline-primary:hover {
  background-color: #0d6efd;
  border-color: #0d6efd;
  color: white;
}

.service-buttons-compact .btn-outline-success {
  color: #198754;
  border-color: #198754;
}

.service-buttons-compact .btn-outline-success:hover {
  background-color: #198754;
  border-color: #198754;
  color: white;
}
</style>
